﻿package com.reyco1.services
{
	/*
	imports
	*/
    import com.reyco1.extension.DispatchExtension;
	import com.reyco1.events.PayPalEvent;
    import flash.net.*;
	/*
	class
	*/
	
	/**
	 * A tool which allows you to gather information and send it to PayPal for processing.
	 * @author reynaldo.columna
	 * 
	 */	
	public class PayPal extends DispatchExtension 
	{
		/*
		variables
		*/
		private var objRequest:URLRequest;
		private var objVariables:URLVariables;
		private var arrItems:Array;
		/*
		constructor
		*/
        public function PayPal()
		{
			this.arrItems = new Array();
        }
		
		
		/**
		 * Sets the PayPal Cart configuration
		 * @param $configObject:Object  an object containing all the mandatory and optional values needed.
		 * to configure the PayPay Cart. 
		 * 
		 * <p>
		 * Mandatory:
		 * <ul>
		 * 	<li>business:String		your paypal registered email address</li>
		 * 	<li>currency:String		the default currency, for example: "USD" or "GBP"</li>
		 * </ul>
		 * </p>
		 * 
		 * <p>
		 * Optional:
		 * <ul>
		 * 	<li>logo:String					path to a 150x50 px logo to be used in the paypal landing page</li>
		 * 	<li>cancel_return:String		path to a page where the user will be redirected on your site if he cancels his order</li>
		 * 	<li>success_return:String		path to a page where the user will be redirected on your site when he completes his order</li>
		 * 	<li>site:String					a reference to your site</li>
		 * </ul>
		 * </p>
		 * 
		 * @example 
		 * <listing version="3.0" >
		 * var myPP:payPalCart = new payPal();
		 * var objConfig:Object = new Object();
		 * 
		 * objConfig.business = "your email address here";
		 * objConfig.currency = "USD";
		 * 
		 * myPP.configure(objConfig);
		 * </listing>
		 * 
		 */		
		public function configure($configObject:Object):void
		{
			this.objVariables = new URLVariables();
			// mandatory
			this.objVariables.business = $configObject.business;
			this.objVariables.currency_code = $configObject.currency;
			// optional
			this.objVariables.image_url = ($configObject.logo) ? $configObject.logo : "";
			this.objVariables.cancel_return = ($configObject.cancel_return) ? $configObject.cancel_return : "";
			this.objVariables["return"] = ($configObject.success_return) ? $configObject.success_return : "";
			this.objVariables.shopping_url = ($configObject.site) ? $configObject.site : "";
			// default
			this.objVariables.cmd = "_cart";
			this.objVariables.upload = "1";
		}
		
		/**
		 * Registers a purchase item to your PayPal
		 * @param $itemObject:Object	An object with the mandatory "nam"e and "price" values
		 * 
		 * @example
		 * <listing version="3.0" >
		 * myPP.registerItem({name:"Book", price:4.95})
		 * </listing>
		 * 
		 * 
		 */		
		public function registerItem($itemObject:Object):void
		{
			if(!$itemObject.name || !$itemObject.price){
				throw new Error("Item being registered must be an object with a \"name\" value AND a \"price\" value."); 
			}else{
				$itemObject.shipping = $itemObject.shipping ? $itemObject.shipping : 0;
				$itemObject.handling = $itemObject.handling ? $itemObject.handling : 0;
				$itemObject.quantity = 0;
				$itemObject.amount = $itemObject.price;
				this.arrItems.push($itemObject);
			}
		}
		
		/**
		 * Checks out all the items the user has added to the PayPal instance using "addItem"
		 * 
		 * $eventType
		 * com.reyco1.events.PayPalEvent.CHECKOUT
		 * 
		 */		
		public function checkOut():void
		{
			this.objRequest = new URLRequest("https://www.paypal.com/cgi-bin/webscr");
			this.objRequest.method = URLRequestMethod.POST;
			this.arrayToParams()			
			this.objRequest.data = this.objVariables;
			this.dispatchEvent(new PayPalEvent(PayPalEvent.CHECKOUT, {}))
			navigateToURL(this.objRequest);
		}
		
		/**
		 * Adds an item to the "check out basket". This basically means that the is item is ready to be purchased
		 * @param $itemName:String	name of the registered product
		 * 
		 * $eventType
		 * com.reyco1.events.PayPalEvent.ITEM_ADDED
		 * 
		 */		
		public function addItem($itemName:String):void
		{
			var bolItemAdded:Boolean = false;
			for(var a:Number = 0; a<this.arrItems.length; a++){
				if(this.arrItems[a].name == $itemName){
					bolItemAdded = true;
					this.arrItems[a].quantity++;
					this.dispatchEvent(new PayPalEvent(PayPalEvent.ITEM_ADDED, {itemsInCart:this.itemsInCart}))
				}
			}
			if(!bolItemAdded){
				throw new Error("\""+$itemName+"\" is not a registered item.")
			}
		}
		
		/**
		 * Removes and item from the "check out basket" previosly added with the "addItem" method
		 * @param $itemName
		 * 
		 * $eventType
		 * com.reyco1.events.PayPalEvent.ITEM_REMOVED
		 * 
		 */		
		public function removeItem($itemName:String):void
		{
			var bolItemRemoved:Boolean = false;
			for(var a:Number = 0; a<this.arrItems.length; a++){
				if(this.arrItems[a].name == $itemName){
					bolItemRemoved = true;
					if(this.arrItems[a].quantity > 0){
						this.arrItems[a].quantity--;
						this.dispatchEvent(new PayPalEvent(PayPalEvent.ITEM_REMOVED, {itemsInCart:this.itemsInCart}))
					}else{
						this.arrItems[a].quantity = 0;
					}
				}
			}
			if(!bolItemRemoved){
				throw new Error("\""+$itemName+"\" is not a registered item.")
			}
		}
		
		private function arrayToParams():void
		{
			for(var a:Number = 0; a<this.arrItems.length; a++){
				if(this.arrItems[a].quantity > 0){
					this.objVariables["item_name_"+Number(a+1)] = this.arrItems[a].name;
					this.objVariables["amount_"+Number(a+1)] = this.arrItems[a].price;
					this.objVariables["quantity_"+Number(a+1)] = this.arrItems[a].quantity;
					this.objVariables["shipping_"+Number(a+1)] = this.arrItems[a].shipping;
					this.objVariables["handling_"+Number(a+1)] = this.arrItems[a].handling;
				}
			}
		}		
		
		/**
		 * Returns all the items currently in the user "check out basket".
		 * @return Array
		 * 
		 */		
		public function get itemsInCart():Array
		{
			var arrTemp:Array = new Array();
			for(var a:Number = 0; a<this.arrItems.length; a++){
				if(this.arrItems[a].quantity > 0){
					arrTemp.push(this.arrItems[a]);
				}
			}
			return arrTemp;
		}
		
		/**
		 * Returns all the registered items
		 * @return Array
		 * 
		 */		
		public function get registeredItems():Array
		{
			return this.arrItems;
		}
    }
}
